package com.insight.modules.system.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.insight.common.constant.FillRuleConstant;
import com.insight.common.exception.JeecgBootException;
import com.insight.common.util.FillRuleUtil;
import com.insight.common.util.oConvertUtils;
import com.insight.modules.system.entity.SysCategory;
import com.insight.modules.system.mapper.SysCategoryMapper;
import com.yuanqiao.insight.acore.system.vo.TreeSelectModel;
import com.insight.modules.system.service.ISysCategoryService;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
 * @Description: 分类字典
 * @Author: jeecg-boot
 * @Date:   2019-05-29
 * @Version: V1.0
 */
@Service
public class SysCategoryServiceImpl extends ServiceImpl<SysCategoryMapper, SysCategory> implements ISysCategoryService {

	/**
	 * 添加分类
	 * 1. 如果传入了父节点ID，设置父节点的 hasChild = 1
	 * 2. 通过公共规则生成分类编码（code）
	 * 3. 保存分类记录
	 * @param sysCategory 分类实体
	 */
	@Override
	public void addSysCategory(SysCategory sysCategory) {
		String categoryCode = "";
		String categoryPid = ISysCategoryService.ROOT_PID_VALUE; // 默认根节点ID
		String parentCode = null;

		// 如果传入了父节点ID
		if (oConvertUtils.isNotEmpty(sysCategory.getPid())) {
			categoryPid = sysCategory.getPid();

			// PID 不是根节点，说明需要把父节点的hasChild字段设置为1
			if (!ISysCategoryService.ROOT_PID_VALUE.equals(categoryPid)) {
				SysCategory parent = baseMapper.selectById(categoryPid);
				parentCode = parent.getCode();
				if (parent != null && !"1".equals(parent.getHasChild())) {
					parent.setHasChild("1");
					baseMapper.updateById(parent);
				}
			}
		}

		// 通过规则生成分类编码（公共规则配置）
		JSONObject formData = new JSONObject();
		formData.put("pid", categoryPid);
		categoryCode = (String) FillRuleUtil.executeRule(FillRuleConstant.CATEGORY, formData);

		sysCategory.setCode(categoryCode);
		sysCategory.setPid(categoryPid);

		// 插入数据库
		baseMapper.insert(sysCategory);
	}

	/**
	 * 更新分类信息
	 * 1. 如果PID为空，则设置为根节点
	 * 2. 如果父节点不为空，设置父节点hasChild = 1
	 * 3. 更新分类记录
	 * @param sysCategory 分类实体
	 */
	@Override
	public void updateSysCategory(SysCategory sysCategory) {
		if (oConvertUtils.isEmpty(sysCategory.getPid())) {
			sysCategory.setPid(ISysCategoryService.ROOT_PID_VALUE);
		} else {
			SysCategory parent = baseMapper.selectById(sysCategory.getPid());
			if (parent != null && !"1".equals(parent.getHasChild())) {
				parent.setHasChild("1");
				baseMapper.updateById(parent);
			}
		}
		baseMapper.updateById(sysCategory);
	}

	/**
	 * 根据分类编码查询该编码对应的子分类列表（树形结构）
	 * 可能会抛出异常：
	 * - 如果编码不存在
	 * - 如果存在多个同编码数据
	 * @param pcode 父分类编码
	 * @return 子分类树形结构列表
	 * @throws JeecgBootException 编码异常
	 */
	@Override
	public List<TreeSelectModel> queryListByCode(String pcode) throws JeecgBootException {
		String pid = ROOT_PID_VALUE;
		if (oConvertUtils.isNotEmpty(pcode)) {
			List<SysCategory> list = baseMapper.selectList(new LambdaQueryWrapper<SysCategory>().eq(SysCategory::getCode, pcode));
			if (list == null || list.isEmpty()) {
				throw new JeecgBootException("该编码【" + pcode + "】不存在，请核实!");
			}
			if (list.size() > 1) {
				throw new JeecgBootException("该编码【" + pcode + "】存在多个，请核实!");
			}
			pid = list.get(0).getId();
		}
		return baseMapper.queryListByPid(pid, null);
	}

	/**
	 * 根据父ID查询子分类列表（树形结构）
	 * @param pid 父ID
	 * @return 子分类树形结构列表
	 */
	@Override
	public List<TreeSelectModel> queryListByPid(String pid) {
		if (oConvertUtils.isEmpty(pid)) {
			pid = ROOT_PID_VALUE;
		}
		return baseMapper.queryListByPid(pid, null);
	}

	/**
	 * 根据父ID和条件查询子分类列表
	 * @param pid 父ID
	 * @param condition 额外过滤条件
	 * @return 子分类树形结构列表
	 */
	@Override
	public List<TreeSelectModel> queryListByPid(String pid, Map<String, String> condition) {
		if (oConvertUtils.isEmpty(pid)) {
			pid = ROOT_PID_VALUE;
		}
		return baseMapper.queryListByPid(pid, condition);
	}

	/**
	 * 根据分类编码查询分类ID
	 * @param code 分类编码
	 * @return 分类ID
	 */
	@Override
	public String queryIdByCode(String code) {
		return baseMapper.queryIdByCode(code);
	}
}

